package com.arvin.faceDetect.ml

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BlurMaskFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorMatrix
import android.graphics.ColorMatrixColorFilter
import android.graphics.Paint
import android.graphics.Rect
import android.util.Log
import com.arvin.faceDetect.utils.ImageAnalyzer
import com.arvin.faceDetect.utils.Settings
import org.tensorflow.lite.Interpreter
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.lang.Math.pow
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel
import kotlin.math.abs
import kotlin.math.exp
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sqrt

class FaceFeatureExtractor(private val context: Context) {
    private var interpreter: Interpreter? = null
    private val inputSize = 112  // 修改为模型实际需要的输入尺寸
    private val inputChannels = 3  // RGB三通道
    private val featureLength = 512  // 设置为模型输出的特征维度
    private val minFaceQuality = 0.2f  // 进一步降低质量要求阈值
    private val numThreads = 4
    
    // 缓存最近的特征向量，用于加速比对
    private val featureCache = object : LinkedHashMap<String, FloatArray>(100, 0.75f, true) {
        override fun removeEldestEntry(eldest: MutableMap.MutableEntry<String, FloatArray>?): Boolean {
            return size > 100  // 最多缓存100个特征向量
        }
    }

    companion object {
        private const val TAG = "FaceFeatureExtractor"
        private const val MODEL_FILE = "mobilefacenet.tflite"
        private const val THRESHOLD_HIGH = 0.85f  // 高置信度阈值
        private const val THRESHOLD_LOW = 0.65f   // 低置信度阈值
        private const val CACHE_EXPIRE_TIME = 30 * 1000L  // 缓存过期时间：30秒

        /**
         * 将RGB像素值转换为灰度值
         * @param pixel ARGB格式的像素值
         * @return 灰度值（0-255）
         */
        private fun getGrayScale(pixel: Int): Int {
            val r = (pixel shr 16) and 0xff
            val g = (pixel shr 8) and 0xff
            val b = pixel and 0xff
            // 使用加权平均法计算灰度值
            return (r * 0.299 + g * 0.587 + b * 0.114).toInt()
        }

        /**
         * 从assets目录加载模型文件
         * @param context 上下文
         * @param modelFile 模型文件名
         * @return MappedByteBuffer 内存映射的模型文件
         */
        private fun loadModelFile(context: Context, modelFile: String): MappedByteBuffer {
            try {
                val assetFileDescriptor = context.assets.openFd(modelFile)
                val inputStream = FileInputStream(assetFileDescriptor.fileDescriptor)
                val fileChannel = inputStream.channel
                val startOffset = assetFileDescriptor.startOffset
                val declaredLength = assetFileDescriptor.declaredLength
                return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
            } catch (e: Exception) {
                throw RuntimeException("无法加载模型文件 $modelFile: ${e.message}", e)
            }
        }
    }

    init {
        initializeModel()
    }

    private fun initializeModel() {
        try {
            val modelFile = File(context.getExternalFilesDir(null), MODEL_FILE)
            if (!modelFile.exists()) {
                context.assets.open(MODEL_FILE).use { input ->
                    FileOutputStream(modelFile).use { output ->
                        input.copyTo(output)
                    }
                }
            }

            // 创建Interpreter选项，禁用GPU代理
            val options = Interpreter.Options().apply {
                // 设置线程数
                setNumThreads(4)
                // 不使用GPU代理
                // useGpuDelegate() 
            }

            interpreter = Interpreter(modelFile, options)
            Log.d("FaceSDK", "模型初始化成功 - 文件大小: ${modelFile.length()}")
        } catch (e: Exception) {
            Log.e("FaceSDK", "模型初始化失败: ${e.message}")
            throw RuntimeException("模型初始化失败: ${e.message}", e)
        }
    }

    private fun loadModelFile(): MappedByteBuffer {
        try {
            Log.d("FaceSDK", "开始加载人脸特征提取模型")
            val modelFile = loadModelFile(context, MODEL_FILE)
            Log.d("FaceSDK", "模型文件加载成功，大小: ${modelFile.capacity()} 字节")

            return modelFile
        } catch (e: Exception) {
            Log.e("FaceSDK", "模型文件加载失败: ${e.message}", e)
            throw RuntimeException("模型加载失败: ${e.message}", e)
        }
    }

    fun extractFeatures(face: Bitmap): FloatArray {
        try {
            Log.d("FaceSDK", "开始提取人脸特征")
            
            // 检查图片尺寸
            val minFaceSize = Settings.getMinFaceSize(context)
            if (face.width < minFaceSize || face.height < minFaceSize) {
                val msg = "图片尺寸过小: ${face.width}x${face.height}, 最小要求: ${minFaceSize}x${minFaceSize}"
                Log.e("FaceSDK", msg)
                throw IllegalArgumentException(msg)
            }
            Log.d("FaceSDK", "图片尺寸检查通过: ${face.width}x${face.height}")
            
            // 预处理图片
            val processedImage = preprocessImage(face)
            Log.d("FaceSDK", "图片预处理完成，尺寸: ${processedImage.width}x${processedImage.height}")
            
            // 检查图片质量
            val quality = checkImageQuality(processedImage)
            Log.d("FaceSDK", "图片质量评分: $quality")
            if (quality < minFaceQuality) {
                val msg = "图片质量不足，质量评分: $quality"
                Log.e("FaceSDK", msg)
                throw IllegalArgumentException(msg)
            }
            Log.d("FaceSDK", "图片质量检查通过")

            try {
                // 获取图像像素数据
                val pixels = IntArray(inputSize * inputSize)
                processedImage.getPixels(pixels, 0, inputSize, 0, 0, inputSize, inputSize)
                
                // 创建输入缓冲区
                val inputBuffer = ByteBuffer.allocateDirect(1 * inputSize * inputSize * inputChannels * 4)
                inputBuffer.order(ByteOrder.nativeOrder())
                
                // 将RGB像素数据写入ByteBuffer，保持三通道信息
                for (i in 0 until inputSize) {
                    for (j in 0 until inputSize) {
                        val pixel = pixels[i * inputSize + j]
                        // 提取RGB通道并归一化到[-1,1]范围
                        val r = ((pixel shr 16) and 0xFF) / 127.5f - 1.0f
                        val g = ((pixel shr 8) and 0xFF) / 127.5f - 1.0f
                        val b = (pixel and 0xFF) / 127.5f - 1.0f
                        
                        // 写入三个通道
                        inputBuffer.putFloat(r)
                        inputBuffer.putFloat(g)
                        inputBuffer.putFloat(b)
                    }
                }
                inputBuffer.rewind()
                
                // 创建输出缓冲区
                val outputBuffer = ByteBuffer.allocateDirect(1 * featureLength * 4)
                outputBuffer.order(ByteOrder.nativeOrder())
                
                // 运行模型推理
                Log.d("FaceSDK", "开始模型推理")
                interpreter?.run(inputBuffer, outputBuffer)
                Log.d("FaceSDK", "模型推理完成")
                
                // 将输出转换为FloatArray
                outputBuffer.rewind()
                val features = FloatArray(featureLength)
                for (i in 0 until featureLength) {
                    features[i] = outputBuffer.float
                }
                
                // L2归一化
                Log.d("FaceSDK", "开始特征向量归一化")
                val norm = sqrt(features.map { it * it }.sum())
                if (norm > 0) {
                    for (i in features.indices) {
                        features[i] /= norm
                    }
                }
                
                // 评估特征质量
                val featureQuality = evaluateFeatureQuality(features)
                Log.d("FaceSDK", "特征质量评分: $featureQuality")
                
                val minValue = features.minOrNull() ?: 0f
                val maxValue = features.maxOrNull() ?: 0f
                Log.d("FaceSDK", "特征向量范围: $minValue 到 $maxValue")
                
                return features
            } catch (e: Exception) {
                Log.e("FaceSDK", "模型推理过程发生错误", e)
                throw RuntimeException("模型推理失败: ${e.message}", e)
            }
        } catch (e: Exception) {
            Log.e("FaceSDK", "特征提取过程发生错误", e)
            throw e
        }
    }

    private fun preprocessImage(bitmap: Bitmap): Bitmap {
        try {
            Log.d(TAG, "开始预处理图片")
            
            // 调整图片大小为模型输入尺寸
            val scaledBitmap = Bitmap.createScaledBitmap(bitmap, inputSize, inputSize, true)
            Log.d(TAG, "图片缩放完成: ${scaledBitmap.width}x${scaledBitmap.height}")

            // 检查光照条件
            val lightingCondition = ImageAnalyzer.getFaceLightingCondition(
                scaledBitmap,
                Rect(0, 0, scaledBitmap.width, scaledBitmap.height)
            )
            if (lightingCondition.quality == ImageAnalyzer.LightingQuality.POOR) {
                Log.w(TAG, "光照条件不佳")
                throw IllegalArgumentException("光照条件不佳")
            }
            
            var processedBitmap = scaledBitmap
            
            // 仅在必要时进行光照归一化
            if (lightingCondition.brightness < 80 || lightingCondition.brightness > 200) {
                Log.d(TAG, "执行光照归一化")
                processedBitmap = normalizeLighting(processedBitmap, 
                    targetMean = 127f,  // 目标均值调整为中间值
                    targetStdDev = 50f  // 减小标准差范围
                )
            }
            
            // 仅在对比度过低时增强对比度
            if (calculateContrast(processedBitmap) < 0.4f) {
                Log.d(TAG, "执行对比度增强")
                processedBitmap = enhanceContrast(processedBitmap, 
                    minPercentile = 1f,  // 减小拉伸范围
                    maxPercentile = 99f
                )
            }
            
            // 确保图像格式正确
            val finalBitmap = if (processedBitmap.config != Bitmap.Config.ARGB_8888) {
                Log.d(TAG, "转换图像格式为ARGB_8888")
                processedBitmap.copy(Bitmap.Config.ARGB_8888, true)
            } else {
                processedBitmap
            }

            Log.d(TAG, "图片预处理完成")
            return finalBitmap
        } catch (e: Exception) {
            Log.e(TAG, "图片预处理失败: ${e.message}")
            throw e
        }
    }

    private fun applyGaussianBlur(bitmap: Bitmap): Bitmap {
        val output = Bitmap.createBitmap(bitmap.width, bitmap.height, bitmap.config)
        val canvas = Canvas(output)
        val paint = Paint()
        paint.maskFilter = BlurMaskFilter(1.5f, BlurMaskFilter.Blur.NORMAL)
        canvas.drawBitmap(bitmap, 0f, 0f, paint)
        return output
    }

    private fun toGrayscale(bitmap: Bitmap): Bitmap {
        val width = bitmap.width
        val height = bitmap.height
        val grayscaleBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(grayscaleBitmap)
        val paint = Paint().apply {
            colorFilter = ColorMatrixColorFilter(ColorMatrix().apply { setSaturation(0f) })
        }
        canvas.drawBitmap(bitmap, 0f, 0f, paint)
        
        // 验证输出尺寸和格式
        if (grayscaleBitmap.width != width || grayscaleBitmap.height != height) {
            Log.e("FaceSDK", "灰度转换后尺寸不正确: ${grayscaleBitmap.width}x${grayscaleBitmap.height}")
            throw IllegalStateException("灰度转换后尺寸不正确")
        }
        
        if (grayscaleBitmap.config != Bitmap.Config.ARGB_8888) {
            Log.e("FaceSDK", "灰度图像格式不正确: ${grayscaleBitmap.config}")
            throw IllegalStateException("灰度图像格式不正确")
        }
        
        return grayscaleBitmap
    }

    private fun equalizeHistogram(bitmap: Bitmap): Bitmap {
        val width = bitmap.width
        val height = bitmap.height
        val pixels = IntArray(width * height)
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
        
        // 计算直方图
        val histogram = IntArray(256)
        for (pixel in pixels) {
            val gray = (pixel and 0xFF)
            histogram[gray]++
        }
        
        // 计算累积直方图
        val cdf = IntArray(256)
        cdf[0] = histogram[0]
        for (i in 1..255) {
            cdf[i] = cdf[i - 1] + histogram[i]
        }
        
        // 归一化
        val cdfMin = cdf.first { it > 0 }
        val cdfMax = cdf.last()
        val diff = cdfMax - cdfMin
        
        // 应用均衡化
        val equalizedPixels = IntArray(width * height)
        for (i in pixels.indices) {
            val gray = pixels[i] and 0xFF
            val newGray = ((cdf[gray] - cdfMin) * 255.0 / diff).toInt().coerceIn(0, 255)
            equalizedPixels[i] = Color.rgb(newGray, newGray, newGray)
        }
        
        val equalizedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        equalizedBitmap.setPixels(equalizedPixels, 0, width, 0, 0, width, height)
        return equalizedBitmap
    }

    private fun checkImageQuality(bitmap: Bitmap): Float {
        val width = bitmap.width
        val height = bitmap.height
        val pixels = IntArray(width * height)
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
        
        // 1. 清晰度评分
        var sharpnessScore = calculateSharpness(pixels, width, height)
        
        // 2. 亮度评分
        val brightnessScore = calculateBrightness(pixels)
        
        // 3. 对比度评分
        val contrastScore = calculateContrast(pixels)
        
        // 综合评分 (加权平均)
        val finalScore = (sharpnessScore * 0.4f + brightnessScore * 0.3f + contrastScore * 0.3f)
            .coerceIn(0f, 1f)
        
        Log.d("FaceFeatureExtractor", "质量评分详情 - 清晰度: $sharpnessScore, 亮度: $brightnessScore, 对比度: $contrastScore, 最终: $finalScore")
        
        return finalScore
    }
    
    private fun calculateSharpness(pixels: IntArray, width: Int, height: Int): Float {
        var sumLaplacian = 0.0
        var count = 0
        
        // 使用简化的Laplacian算子，降低要求
        for (y in 1 until height - 1 step 2) {
            for (x in 1 until width - 1 step 2) {
                val idx = y * width + x
                val center = pixels[idx] and 0xFF
                val top = pixels[idx - width] and 0xFF
                val bottom = pixels[idx + width] and 0xFF
                val left = pixels[idx - 1] and 0xFF
                val right = pixels[idx + 1] and 0xFF
                
                // 简化的Laplacian计算
                val laplacian = abs(4 * center - top - bottom - left - right)
                
                // 降低边缘检测阈值
                if (laplacian > 10) {  // 进一步降低阈值
                    sumLaplacian += laplacian
                    count++
                }
            }
        }
        
        // 调整归一化系数
        return if (count > 0) {
            (sumLaplacian / (count * 150.0)).toFloat().coerceIn(0f, 1f)
        } else {
            0f
        }
    }
    
    private fun calculateBrightness(pixels: IntArray): Float {
        var sum = 0L
        for (pixel in pixels) {
            sum += pixel and 0xFF
        }
        
        val avgBrightness = sum.toFloat() / pixels.size
        
        // 将亮度值映射到0-1范围，使用更宽松的范围
        // 理想亮度范围：50-200
        return when {
            avgBrightness < 30 -> avgBrightness / 30f  // 过暗
            avgBrightness > 220 -> (255 - avgBrightness) / 35f  // 过亮
            avgBrightness in 50f..200f -> 1f  // 理想范围
            avgBrightness in 30f..50f -> 0.7f + (avgBrightness - 30) / 20f * 0.3f  // 稍暗
            else -> 0.7f + (220 - avgBrightness) / 20f * 0.3f  // 稍亮
        }
    }
    
    private fun calculateContrast(bitmap: Bitmap): Float {
        val width = bitmap.width
        val height = bitmap.height
        val pixels = IntArray(width * height)
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
        return calculateContrast(pixels)
    }
    
    private fun calculateContrast(pixels: IntArray): Float {
        var min = 255
        var max = 0
        
        // 计算实际的最大最小值
        for (pixel in pixels) {
            val gray = pixel and 0xFF
            if (gray < min) min = gray
            if (gray > max) max = gray
        }
        
        val contrast = (max - min).toFloat()
        
        // 将对比度映射到0-1范围
        // 理想对比度范围：50-200
        return when {
            contrast < 30 -> contrast / 30f  // 对比度太低
            contrast > 220 -> (255 - contrast) / 35f  // 对比度太高
            contrast in 50f..200f -> 1f  // 理想范围
            contrast in 30f..50f -> 0.7f + (contrast - 30) / 20f * 0.3f  // 稍低
            else -> 0.7f + (220 - contrast) / 20f * 0.3f  // 稍高
        }
    }

    private fun extractEnhancedFeatures(bitmap: Bitmap): FloatArray {
        val width = bitmap.width
        val height = bitmap.height
        val pixels = IntArray(width * height)
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
        
        // 使用更轻量级的特征提取方法
        val features = ArrayList<Float>()
        
        // 1. 简化的LBP特征 (使用4x4网格)
        val gridSize = 4
        val cellWidth = width / gridSize
        val cellHeight = height / gridSize
        
        for (gy in 0 until gridSize) {
            for (gx in 0 until gridSize) {
                val startX = gx * cellWidth
                val startY = gy * cellHeight
                val endX = minOf((gx + 1) * cellWidth, width)
                val endY = minOf((gy + 1) * cellHeight, height)
                
                // 计算每个网格的简化LBP特征
                var lbpSum = 0f
                var count = 0
                
                for (y in startY until endY step 2) {  // 步长为2，减少计算量
                    for (x in startX until endX step 2) {
                        if (x > 0 && x < width - 1 && y > 0 && y < height - 1) {
                            val center = getGrayScale(pixels[y * width + x])
                            val top = getGrayScale(pixels[(y - 1) * width + x])
                            val right = getGrayScale(pixels[y * width + x + 1])
                            val bottom = getGrayScale(pixels[(y + 1) * width + x])
                            val left = getGrayScale(pixels[y * width + x - 1])
                            
                            // 使用4邻域简化LBP
                            var lbpValue = 0
                            if (top >= center) lbpValue = lbpValue or 1
                            if (right >= center) lbpValue = lbpValue or 2
                            if (bottom >= center) lbpValue = lbpValue or 4
                            if (left >= center) lbpValue = lbpValue or 8
                            
                            lbpSum += lbpValue
                            count++
                        }
                    }
                }
                
                features.add(if (count > 0) lbpSum / (count * 15f) else 0f)  // 归一化到0-1
            }
        }
        
        // 2. 梯度直方图特征 (简化版HOG)
        val binCount = 8  // 减少方向数量
        for (gy in 0 until gridSize) {
            for (gx in 0 until gridSize) {
                val startX = gx * cellWidth
                val startY = gy * cellHeight
                val endX = minOf((gx + 1) * cellWidth, width - 1)
                val endY = minOf((gy + 1) * cellHeight, height - 1)
                
                val histogram = FloatArray(binCount)
                var totalMagnitude = 0f
                
                for (y in startY until endY step 2) {
                    for (x in startX until endX step 2) {
                        val dx = getGrayScale(pixels[y * width + minOf(x + 1, endX)]) -
                                getGrayScale(pixels[y * width + x])
                        val dy = getGrayScale(pixels[minOf(y + 1, endY) * width + x]) -
                                getGrayScale(pixels[y * width + x])
                        
                        val magnitude = sqrt(dx * dx + dy * dy.toFloat())
                        val angle = Math.toDegrees(Math.atan2(dy.toDouble(), dx.toDouble())).toFloat()
                        val bin = (((angle + 180) * binCount / 360) % binCount).toInt()
                        
                        histogram[bin] += magnitude
                        totalMagnitude += magnitude
                    }
                }
                
                // 归一化直方图
                if (totalMagnitude > 0) {
                    for (i in 0 until binCount) {
                        features.add(histogram[i] / totalMagnitude)
                    }
                } else {
                    features.addAll(List(binCount) { 0f })
                }
            }
        }
        
        // 3. 亮度统计特征
        for (gy in 0 until gridSize) {
            for (gx in 0 until gridSize) {
                val startX = gx * cellWidth
                val startY = gy * cellHeight
                val endX = minOf((gx + 1) * cellWidth, width)
                val endY = minOf((gy + 1) * cellHeight, height)
                
                var sum = 0f
                var sumSquared = 0f
                var count = 0
                
                for (y in startY until endY step 2) {
                    for (x in startX until endX step 2) {
                        val gray = getGrayScale(pixels[y * width + x])
                        sum += gray
                        sumSquared += gray * gray
                        count++
                    }
                }
                
                if (count > 0) {
                val mean = sum / count
                val variance = (sumSquared / count) - (mean * mean)
                    features.add(mean / 255f)  // 归一化均值
                    features.add(sqrt(maxOf(0f, variance)) / 255f)  // 归一化标准差
                } else {
                    features.add(0f)
                    features.add(0f)
                }
            }
        }
        
        // 确保特征向量长度符合要求
        return if (features.size >= featureLength) {
            features.subList(0, featureLength).toFloatArray()
        } else {
            features.toFloatArray().copyOf(featureLength)
        }
    }

    fun compareFaces(features1: FloatArray, features2: FloatArray): Float {
        try {
            Log.d("FaceSDK", "开始人脸特征比对")
            if (features1.size != features2.size) {
                val msg = "特征向量长度不匹配: ${features1.size} vs ${features2.size}"
                Log.e("FaceSDK", msg)
                throw IllegalArgumentException(msg)
            }
            
            // 计算余弦相似度
            var dotProduct = 0.0
            var norm1 = 0.0
            var norm2 = 0.0
            
            for (i in features1.indices) {
                dotProduct += features1[i] * features2[i]
                norm1 += features1[i] * features1[i]
                norm2 += features2[i] * features2[i]
            }
            
            val similarity = if (norm1 > 0 && norm2 > 0) {
                dotProduct / (sqrt(norm1) * sqrt(norm2))
            } else {
                0.0
            }
            
            // 使用sigmoid函数将相似度映射到[0,1]区间，并增强差异
            val adjustedSimilarity = 1.0 / (1.0 + exp(-10.0 * (similarity - 0.5)))
            
            // 应用非线性变换增强高相似度区域的差异
            val finalSimilarity = if (adjustedSimilarity > 0.5) {
                val enhancedDiff =  pow(adjustedSimilarity - 0.5, 0.7)
                0.5 + enhancedDiff * 0.5
            } else {
                adjustedSimilarity
            }.toFloat()
            
            Log.d("FaceSDK", "特征比对完成 - 原始相似度: $similarity, 调整后相似度: $finalSimilarity")
            return finalSimilarity
        } catch (e: Exception) {
            Log.e("FaceSDK", "特征比对失败: ${e.message}")
            throw e
        }
    }

    // 添加特征向量质量评估函数
    fun evaluateFeatureQuality(features: FloatArray): Float {
        try {
            var sum = 0f
            var sumSquares = 0f
            var maxVal = Float.MIN_VALUE
            var minVal = Float.MAX_VALUE

            // 计算基础统计量
            for (feature in features) {
                sum += feature
                sumSquares += feature * feature
                maxVal = max(maxVal, feature)
                minVal = min(minVal, feature)
            }

            val mean = sum / features.size
            val variance = (sumSquares / features.size) - (mean * mean)
            val range = maxVal - minVal

            // 计算特征分布得分
            val varianceScore = min(variance * 10f, 1f)  // 增加方差权重
            val rangeScore = min(range * 5f, 1f)         // 考虑特征值范围
            val magnitudeScore = min(abs(mean) * 3f, 1f) // 考虑特征均值

            // 综合评分，调整权重
            val qualityScore = (varianceScore * 0.5f +
                    rangeScore * 0.3f +
                    magnitudeScore * 0.2f)

            Log.d(
                "FaceSDK", "特征质量评估 - 均值: $mean, 方差: $variance, " +
                        "范围: $range, 最终得分: $qualityScore"
            )

            return qualityScore

        } catch (e: Exception) {
            Log.e("FaceSDK", "特征质量评估失败: ${e.message}")
            throw e
        }
    }

    private fun Float.pow(exponent: Float): Float {
        return Math.pow(this.toDouble(), exponent.toDouble()).toFloat()
    }

    fun cropFace(bitmap: Bitmap, boundingBox: Rect): Bitmap {
        val width = boundingBox.width()
        val height = boundingBox.height()

        // 扩大裁剪区域以包含更多面部特征
        val expandRatio = 0.1f
        val expandX = (width * expandRatio).toInt()
        val expandY = (height * expandRatio).toInt()

        val left = (boundingBox.left - expandX).coerceAtLeast(0)
        val top = (boundingBox.top - expandY).coerceAtLeast(0)
        val right = (boundingBox.right + expandX).coerceAtMost(bitmap.width)
        val bottom = (boundingBox.bottom + expandY).coerceAtMost(bitmap.height)
        
        return Bitmap.createBitmap(bitmap, left, top, right - left, bottom - top)
    }

    private fun enhanceContrast(bitmap: Bitmap, minPercentile: Float = 1f, maxPercentile: Float = 99f): Bitmap {
        val width = bitmap.width
        val height = bitmap.height
        val pixels = IntArray(width * height)
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)
        
        // 分别处理RGB通道
        val rValues = IntArray(pixels.size)
        val gValues = IntArray(pixels.size)
        val bValues = IntArray(pixels.size)

        // 分离RGB通道
        for (i in pixels.indices) {
            val pixel = pixels[i]
            rValues[i] = Color.red(pixel)
            gValues[i] = Color.green(pixel)
            bValues[i] = Color.blue(pixel)
        }

        // 分别计算每个通道的最小值和最大值
        val rMinMax = calculateMinMax(rValues, minPercentile, maxPercentile)
        val gMinMax = calculateMinMax(gValues, minPercentile, maxPercentile)
        val bMinMax = calculateMinMax(bValues, minPercentile, maxPercentile)

        Log.d(
            "FaceSDK", "对比度增强 - R通道范围: ${rMinMax.first}-${rMinMax.second}, " +
                    "G通道范围: ${gMinMax.first}-${gMinMax.second}, " +
                    "B通道范围: ${bMinMax.first}-${bMinMax.second}"
        )

        // 应用对比度拉伸到每个通道
        for (i in pixels.indices) {
            val r = stretchChannel(rValues[i], rMinMax.first, rMinMax.second)
            val g = stretchChannel(gValues[i], gMinMax.first, gMinMax.second)
            val b = stretchChannel(bValues[i], bMinMax.first, bMinMax.second)

            // 保持原始alpha通道
            val alpha = pixels[i] and 0xFF000000.toInt()
            pixels[i] = alpha or (r shl 16) or (g shl 8) or b
        }

        val resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        resultBitmap.setPixels(pixels, 0, width, 0, 0, width, height)
        return resultBitmap
    }

    private fun calculateMinMax(
        values: IntArray,
        minPercentile: Float,
        maxPercentile: Float
    ): Pair<Int, Int> {
        val sorted = values.sortedArray()
        val minIndex = ((values.size * minPercentile) / 100f).toInt().coerceIn(0, values.size - 1)
        val maxIndex = ((values.size * maxPercentile) / 100f).toInt().coerceIn(0, values.size - 1)
        return Pair(sorted[minIndex], sorted[maxIndex])
    }

    private fun stretchChannel(value: Int, min: Int, max: Int): Int {
        return ((value - min) * 255.0 / (max - min)).toInt().coerceIn(0, 255)
    }

    private fun normalizeLighting(
        bitmap: Bitmap,
        targetMean: Float = 127f,
        targetStdDev: Float = 50f
    ): Bitmap {
        val width = bitmap.width
        val height = bitmap.height
        val pixels = IntArray(width * height)
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height)

        // 分别计算每个通道的均值和标准差
        var rSum = 0.0
        var gSum = 0.0
        var bSum = 0.0

        pixels.forEach { pixel ->
            rSum += Color.red(pixel)
            gSum += Color.green(pixel)
            bSum += Color.blue(pixel)
        }

        val size = pixels.size
        val rMean = rSum / size
        val gMean = gSum / size
        val bMean = bSum / size

        var rVariance = 0.0
        var gVariance = 0.0
        var bVariance = 0.0

        pixels.forEach { pixel ->
            rVariance += (Color.red(pixel) - rMean) * (Color.red(pixel) - rMean)
            gVariance += (Color.green(pixel) - gMean) * (Color.green(pixel) - gMean)
            bVariance += (Color.blue(pixel) - bMean) * (Color.blue(pixel) - bMean)
        }

        val rStdDev = sqrt(rVariance / size)
        val gStdDev = sqrt(gVariance / size)
        val bStdDev = sqrt(bVariance / size)

        Log.d("FaceSDK", "光照归一化 - R通道: 均值=$rMean, 标准差=$rStdDev")
        Log.d("FaceSDK", "光照归一化 - G通道: 均值=$gMean, 标准差=$gStdDev")
        Log.d("FaceSDK", "光照归一化 - B通道: 均值=$bMean, 标准差=$bStdDev")

        // 分别归一化每个通道
        for (i in pixels.indices) {
            val pixel = pixels[i]
            val alpha = pixel and 0xFF000000.toInt()

            val r = normalizeChannel(
                Color.red(pixel),
                rMean.toFloat(),
                rStdDev.toFloat(),
                targetMean,
                targetStdDev
            )
            val g = normalizeChannel(
                Color.green(pixel),
                gMean.toFloat(),
                gStdDev.toFloat(),
                targetMean,
                targetStdDev
            )
            val b = normalizeChannel(
                Color.blue(pixel),
                bMean.toFloat(),
                bStdDev.toFloat(),
                targetMean,
                targetStdDev
            )

            pixels[i] = alpha or (r shl 16) or (g shl 8) or b
        }

        val resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        resultBitmap.setPixels(pixels, 0, width, 0, 0, width, height)
        return resultBitmap
    }

    private fun normalizeChannel(
        value: Int,
        mean: Float,
        stdDev: Float,
        targetMean: Float,
        targetStdDev: Float
    ): Int {
        return if (stdDev > 0) {
            ((value - mean) * (targetStdDev / stdDev) + targetMean).toInt().coerceIn(0, 255)
        } else {
            value
        }
    }

    fun release() {
        interpreter?.close()
        interpreter = null
    }
} 